package com.training.admin.service.impl;

import java.util.ArrayList;
import java.util.Date;
import java.util.HashMap;
import java.util.List;
import java.util.Map;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;
import com.demo2do.core.entity.exception.BusinessException;
import com.demo2do.core.entity.result.HttpResult;
import com.demo2do.core.persistence.GenericDaoSupport;
import com.demo2do.core.persistence.annotation.Dao;
import com.demo2do.core.utils.CollectionUtils;
import com.demo2do.core.utils.DateFormatUtils;
import com.training.admin.dao.CourseTraineeStatDao;
import com.training.admin.dao.ProjectPhaseCourseDao;
import com.training.admin.dao.ProjectTraineeDao;
import com.training.admin.dao.TraineeDao;
import com.training.admin.dao.TrainingResultDao;
import com.training.admin.entity.project.CourseTraineeStat;
import com.training.admin.entity.project.Project;
import com.training.admin.entity.project.ProjectPhase;
import com.training.admin.entity.project.ProjectPhaseCourse;
import com.training.admin.entity.project.ProjectTrainee;
import com.training.admin.entity.project.TrainingResult;
import com.training.admin.entity.trainee.Trainee;
import com.training.admin.service.CourseTraineeStatService;

/**
 * 
 * @author mohanlan
 *
 */
@Service("courseTraineeStatService")
public class CourseTraineeStatServiceImpl implements CourseTraineeStatService {
    
    private static final Logger logger = LoggerFactory.getLogger(CourseTraineeStatService.class);
    
    @Dao
    private TrainingResultDao trainingResultDao;
    
    @Autowired
    private GenericDaoSupport genericDaoSupport;
    
    @Dao
    private ProjectPhaseCourseDao projectPhaseCourseDao;
    
    @Dao
    private ProjectTraineeDao projectTraineeDao;
    
    @Dao
    private CourseTraineeStatDao courseTraineeStatDao;
    
    @Dao
    private TraineeDao traineeDao;
    
    /*
     * (non-Javadoc)
     * @see com.training.admin.service.CourseTraineeStatService#generateCourseTrainStat()
     */
    @SuppressWarnings("unchecked")
    public void generateCourseTrainStat() {
        
        logger.info("start generate at [{}]", DateFormatUtils.format(new Date(), "yyyy-MM-dd HH:mm:ss"));
        
        // Step1 : List all not_scanned training_result  sql1  limit 300
        List<TrainingResult> trainingResults = trainingResultDao.listByNotScanned(0, 300);
        
        if(org.apache.commons.collections.CollectionUtils.isNotEmpty(trainingResults)) {
         // Step2 : List<phase> phases
            List<ProjectPhase> projectPhases = CollectionUtils.extractPropertyList(trainingResults, "projectPhase");
            
            // Step3: List<ProjectIds>
            List<Long> projectIds = CollectionUtils.extractPropertyList(projectPhases, "project.id");
            
            // Step4: Map<String, List<ProjectTrainee>>
            List<ProjectTrainee> projectTrainees = projectTraineeDao.listByProjectIds(projectIds);
            List<Long> traineeIds = CollectionUtils.extractPropertyList(projectTrainees, "trainee.id");
            
            // Step5: Map<String, List<ProjectPhaseCourse>> key phase
            List<ProjectPhaseCourse> projectPhaseCourses = projectPhaseCourseDao.listProjectPhaseCourse();
            Map<String, List<ProjectPhaseCourse>> projectPhaseCoursesMap = CollectionUtils.constructMapValues(projectPhaseCourses, "projectPhase.id");
            
            // Step6: Map<String, Map<String, CourseTraineeStat>>  key1 trainee.id    key2 course.i
            List<CourseTraineeStat> courseTraineeStats = courseTraineeStatDao.list(traineeIds);
            
            Map<String, Map<String, CourseTraineeStat>> coursetraineeStatsMap = new HashMap<String, Map<String, CourseTraineeStat>>();
            Map<String, List<CourseTraineeStat>> traineeCourseStatListMap = CollectionUtils.constructMapValues(courseTraineeStats, "trainee.id");
            for(String key : traineeCourseStatListMap.keySet()) {
                List<CourseTraineeStat> item = traineeCourseStatListMap.get(key);
                Map<String, CourseTraineeStat> itemMap = CollectionUtils.constructMapValue(item, "course.id");
                coursetraineeStatsMap.put(key, itemMap);
            }
            
            // Step7: for trainingResult
            for(TrainingResult trainingResult : trainingResults) {
                
                Long traineeId = trainingResult.getTrainee().getId();
                Long phaseId = trainingResult.getProjectPhase().getId();
                
                List<ProjectPhaseCourse> projectPhaseCourseMapItem = projectPhaseCoursesMap.get(phaseId.toString());
                if(org.apache.commons.collections.CollectionUtils.isNotEmpty(projectPhaseCourseMapItem)) {
                    for(ProjectPhaseCourse projectPhaseCourse : projectPhaseCourseMapItem) {
                        
                        Long courseId = projectPhaseCourse.getCourse().getId();
                        
                        CourseTraineeStat courseTraineeStat = null;
                        Map<String, CourseTraineeStat> traineeCourseStatItem = coursetraineeStatsMap.get(traineeId.toString());
                        if(traineeCourseStatItem != null && traineeCourseStatItem.size() > 0) {
                            courseTraineeStat = traineeCourseStatItem.get(courseId.toString());
                        }
                        
                        if(courseTraineeStat != null) {
                            genericDaoSupport.update(courseTraineeStat.autoCount(courseTraineeStat.getCount()));
                        } else {
                            courseTraineeStat = new CourseTraineeStat(trainingResult.getTrainee(), projectPhaseCourse.getCourse());
                            genericDaoSupport.save(courseTraineeStat);
                        }
                    }
                }
                
                // Step8 update traineeResult
                genericDaoSupport.update(trainingResult.setToScanned());
            }
        }
    }
    
    /*
     * (non-Javadoc)
     * @see com.training.admin.service.CourseTraineeStatService#finishedFeiRen(java.lang.String)
     */
    public HttpResult finishedFeiRen(String email) {
        
        HttpResult httpResult = new HttpResult();
        
        Boolean result = false;
        
        List<Long> feiRenProjectIds = new ArrayList<Long>();
        feiRenProjectIds.add(new Long(15));
        feiRenProjectIds.add(new Long(16));
        
        Trainee trainee = traineeDao.loadByEmail(email);
        if(trainee == null || trainee.isDisabled()) {
            logger.error("current email has no trainee [{}]", email);
            throw BusinessException.newInstance("500", "学员不存在");
        }
        
        List<ProjectTrainee> projectTrainees = projectTraineeDao.listTrainee(trainee, feiRenProjectIds);
        
        if(org.apache.commons.collections.CollectionUtils.isNotEmpty(projectTrainees)) {
            result = true;
            httpResult.success().data("result", result).message("成功");
        } else {
            httpResult.success().data("result", result).message("失败");
        }
        
        return httpResult;
    }

    /* (non-Javadoc)
     * @see com.training.admin.service.CourseTraineeStatService#listCourseTraineeStats(java.util.List, java.util.List)
     */
    @SuppressWarnings("unchecked")
    public Map<String, Boolean> listCourseTraineeStats(String email, List<Long> courseIds) {
        
        Map<String, Boolean> result = new HashMap<String, Boolean>();
        
        Trainee trainee = traineeDao.loadByEmail(email);
        if(trainee == null || trainee.isDisabled()) {
            logger.error("current email has no trainee [{}]", email);
            throw BusinessException.newInstance("500", "学员不存在");
        }
        
        List<Project> projects = projectTraineeDao.listProject(trainee);
        if(org.apache.commons.collections.CollectionUtils.isNotEmpty(projects)) {
            
            List<Long> projectIds = CollectionUtils.extractPropertyList(projects, "id");
            List<TrainingResult> trainingResults = trainingResultDao.listByProject(email);
            List<ProjectPhaseCourse> projectPhaseCourses = projectPhaseCourseDao.listByProjects(projectIds, courseIds);
            Map<String, List<ProjectPhaseCourse>> projectPhaseCoursesMap = CollectionUtils.constructMapValues(projectPhaseCourses, "projectPhase.id");
            for(TrainingResult trainingResult : trainingResults) {
                if(trainingResult.getScore() > 0) {
                    String phaseIdString = trainingResult.getProjectPhase().getId().toString();
                    List<ProjectPhaseCourse> projectPhaseCourses2 = projectPhaseCoursesMap.get(phaseIdString);
                    if(org.apache.commons.collections.CollectionUtils.isNotEmpty(projectPhaseCourses2)) {
                        for(ProjectPhaseCourse projectPhaseCourse : projectPhaseCourses2) {
                            if(!projectPhaseCourse.getCourse().isDisabled()) {
                                String courseIdString = projectPhaseCourse.getCourse().getId().toString();
                                Boolean item = result.get(courseIdString);
                                if(item == null || item == false) {
                                    result.put(courseIdString, true);
                                }
                            }
                        }
                        
                    }
                }
            }
            
            return result;
        }
        
        logger.error("current trainee has no projects");
        throw BusinessException.newInstance("500", "学员未参加任何项目");
    }
}
